package com.javayh.common.date;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @author Dylan Yang
 * @Title: DateUtil
 * @ProjectName lucky
 * @Description: TODO
 * @date 2018/10/712:18
 */
public class DateUtil {

    /**
     * 时间转时间戳
     *
     * @param date
     *            时间
     * @return 时间戳
     */
    public static long dateToStamp(Date date) {
        return date.getTime();
    }

    /**
     * 时间戳转时间
     *
     * @param stamp
     *            时间戳
     * @return 时间
     */
    public static Date stampToDate(long stamp) {
        return new Date(stamp);
    }

    /**
     * 将入参的时间间隔一定时间后得到新的时间,正向后间隔,零不变,负向前间隔
     *
     * @param date
     *            入参的时间
     * @param years
     *            年
     * @param months
     *            月
     * @param days
     *            日
     * @param hours
     *            小时
     * @param minutes
     *            分
     * @param seconds
     *            秒
     * @return 间隔后的时间
     */
    public static Date dateInterval(Date date, long years, long months, long days, long hours, long minutes,
                                    long seconds) {
        LocalDateTime localDateTime = dateToLocalDateTime(date).plusYears(years).plusMonths(months).plusDays(days)
                .plusHours(hours).plusMinutes(minutes).plusSeconds(seconds);
        return locaDateTimeToDate(localDateTime);
    }

    /**
     * 将入参的时间间隔某一个类型的时间间隔后得到新时间,正向后间隔,零不变,负向前间隔
     *
     * @param date
     *            入参的时间
     * @param period
     *            间隔的时间
     * @param type
     *            间隔的时间类型
     * @return 间隔后的时间
     */
    public static Date dateInterval(Date date, long period, String type) {
        if (type == null || "".equals(type)) {
            type = "days";
        }
        LocalDateTime localDateTime = dateToLocalDateTime(date);
        switch (type) {
            case "years":
                localDateTime = localDateTime.plusYears(period);
                break;
            case "months":
                localDateTime = localDateTime.plusMonths(period);
                break;
            case "days":
                localDateTime = localDateTime.plusDays(period);
                break;
            case "hours":
                localDateTime = localDateTime.plusHours(period);
                break;
            case "minutes":
                localDateTime = localDateTime.plusMinutes(period);
                break;
            case "seconds":
                localDateTime = localDateTime.plusSeconds(period);
                break;
            default:
                throw new IllegalArgumentException("参数(type)错误:\ntype只能为years/months/days/hours/minutes/seconds 中的某一个");
        }

        return locaDateTimeToDate(localDateTime);
    }

    /**
     * 将入参的时间间隔某天数后得到新时间,正向后间隔,零不变,负向前间隔
     *
     * @param date
     *            入参时间
     * @param period
     *            间隔的天数
     * @return 间隔后的时间
     */
    public static Date dateInterval(Date date, long period) {
        return locaDateTimeToDate(dateToLocalDateTime(date).plusDays(period));
    }

    /**
     * Date转LocalDateTime
     *
     * @param date
     * @return LocalDateTime
     */
    public static LocalDateTime dateToLocalDateTime(Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    }

    /**
     * LocalDate转Date
     *
     * @param localDate
     * @return Date(只含日期不含时分秒)
     */
    public static Date localDateToDate(LocalDate localDate) {
        return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * LocalDateTime转Date
     *
     * @param localDateTime
     * @return Date(含有时分秒)
     */
    public static Date locaDateTimeToDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获得起始时间与终止时间之间的间隔天数(或小时或分钟)
     *
     * @param startDate
     *            起始时间
     * @param stopDate
     *            终止时间
     * @param type
     *            间隔类型
     * @return 间隔天数 (或小时或分钟)
     */
    public static long intervalTime(Date startDate, Date stopDate, String type) {
        long temp = 0;
        long intervalMilliSeconds = stopDate.getTime() - startDate.getTime();
        switch (type) {
            case "days":
                temp = TimeUnit.MILLISECONDS.toDays(intervalMilliSeconds);
                break;
            case "hours":
                temp = TimeUnit.MILLISECONDS.toHours(intervalMilliSeconds);
                break;
            case "minutes":
                temp = TimeUnit.MILLISECONDS.toMinutes(intervalMilliSeconds);
                break;
            default:
                throw new IllegalArgumentException("参数(type)错误:\ntype只能为/days/hours/minutes 中的某一个");
        }
        return temp;
    }

    /**
     * 获得起始时间与终止时间之间的间隔天数
     *
     * @param startDate
     *            起始时间
     * @param stopDate
     *            终止时间
     * @return 间隔天数
     */
    public static long intervalTime(Date startDate, Date stopDate) {
        return TimeUnit.MILLISECONDS.toDays(stopDate.getTime() - startDate.getTime());
    }

    /**
     * 时间转字符串
     *
     * @param date
     *            时间
     * @param pattern
     *            格式 (yyyyMMdd HH:mm:ss)
     * @return 格式化后的字符串
     */
    public static String dateToStr(Date date, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(date);
    }

    /**
     * 字符串转时间
     *
     * @param dateStr
     *            时间格式的字符串
     * @param pattern
     *            字符串的时间格式
     * @return 格式化后的时间
     * @throws ParseException
     */
    public static Date strToDate(String dateStr, String pattern) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.parse(dateStr);
    }

}



